package net.airtheva.hexagonMatrix;

import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import java.util.ArrayList;

import javax.microedition.khronos.opengles.GL10;

import net.airtheva.hexagonMatrix.data.Vector3f;
import net.airtheva.hexagonMatrix.data.Vector4f;
import net.airtheva.hexagonMatrix.data.Vertex;

public class Mesh extends BaseComponent {

	public static final Vector4f COLOR_MESH = new Vector4f(new float[] {
		132.0f / 255.0f,
		132.0f / 255.0f,
		132.0f / 255.0f,
		1.0f
	});
	public static final Vector4f COLOR_X_AXIS = new Vector4f(new float[] {
		1.0f,
		0.0f,
		0.0f,
		1.0f
	});
	public static final Vector4f COLOR_Y_AXIS = new Vector4f(new float[] {
		0.0f,
		1.0f,
		0.0f,
		1.0f
	});
	Vertex[] mVertices = null;
	
	FloatBuffer mPositionBuffer = null;
	FloatBuffer mColorBuffer = null;
	
	public Mesh(Surface surface, int amount) {
		// TODO Auto-generated constructor stub
		super(surface);
		
		ArrayList<Vertex> vertices = new ArrayList<Vertex>();
		
		// X.
		// When i = - amount, the border will be drawn.
		for(int i = - amount + 1; i < amount; i++) {
			if(i == 0) {
				vertices.add(new Vertex().Position(i, amount, 0.0f).Color(COLOR_X_AXIS));
				vertices.add(new Vertex().Position(i, - amount, 0.0f).Color(COLOR_X_AXIS));
			}
			else {
				vertices.add(new Vertex().Position(i, amount, 0.0f).Color(COLOR_MESH));
				vertices.add(new Vertex().Position(i, - amount, 0.0f).Color(COLOR_MESH));
			}
		}
		
		// Y.
		for(int i = - amount + 1; i < amount; i++) {
			if(i == 0) {
				vertices.add(new Vertex().Position(amount, i, 0.0f).Color(COLOR_Y_AXIS));
				vertices.add(new Vertex().Position(- amount, i, 0.0f).Color(COLOR_Y_AXIS));
			}
			else {
				vertices.add(new Vertex().Position(amount, i, 0.0f).Color(COLOR_MESH));
				vertices.add(new Vertex().Position(- amount, i, 0.0f).Color(COLOR_MESH));
			}
		}
		
		mVertices = vertices.toArray(new Vertex[] {});
		
		makeBuffer();
		
	}
	
	@Override
	protected void makeBuffer() {
		// TODO Auto-generated method stub

		mPositionBuffer = ByteBuffer.allocateDirect(mVertices.length * Vector3f.SIZE).order(ByteOrder.nativeOrder()).asFloatBuffer();
		
		mColorBuffer = ByteBuffer.allocateDirect(mVertices.length * Vector4f.SIZE).order(ByteOrder.nativeOrder()).asFloatBuffer();
		
		for(int i = 0; i < mVertices.length; i++) {
			Vertex vertex = mVertices[i];
			mPositionBuffer.put(vertex.Position.Data);
			mColorBuffer.put(vertex.Color.Data);
		}
		
		mPositionBuffer.position(0);
		mColorBuffer.position(0);
		
	}

	@Override
	public void Draw(GL10 gl) {
		// TODO Auto-generated method stub

		preDraw(gl);
		
		gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
		gl.glVertexPointer(3, GL10.GL_FLOAT, 0, mPositionBuffer);
		gl.glEnableClientState(GL10.GL_COLOR_ARRAY);
		gl.glColorPointer(4, GL10.GL_FLOAT, 0, mColorBuffer);
		
		// Draw lines.
		gl.glDrawArrays(GL10.GL_LINES, 0, mVertices.length);
		
		gl.glDisableClientState(GL10.GL_COLOR_ARRAY);
		gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
		
		gl.glFlush();

	}

}
